<?php

/*
 * 用户认证类
 */

class Sauth {
	
	private $ci = NULL;
	
	private $error = '';
	
	public function __construct()
	{
		
		$this->ci = & get_instance();
		
		log_message('debug', '成功加载认证类');
	}
	
	/*
	 * 返回错误信息
	 */
	public function error()
	{
		return $this->error;	
	}
	
	/*
	 * 返回用户id
	 */
	public function get_user_id()
	{
		return $this->ci->session->userdata('s_user_id');
	}
	
	/*
	 * 返回用户名
	 */
	public function get_username()
	{
		return $this->ci->session->userdata('s_username');	
	}
	
	/*
	 * 获取用户角色id
	 */
	public function get_role_id()
	{
		return $this->ci->session->userdata('s_role_id');
	}

	/*
	 * 获取用户角色名
	 */
	public function get_role_name()
	{
		return $this->ci->session->userdata('s_role_name');
	}

	/*
	 * 是否已经登录
	 */
	public function is_login()
	{
		return $this->ci->session->userdata('s_login') ? TRUE : FALSE;
	}
	
	/*
	 * 是否管理员
	 * 是返回true,否则返回false
	 */
	public function is_admin()
	{
		return ($this->ci->session->userdata('s_parent_role_id')==1) ? TRUE : FALSE;
	}
	
	/*
	 * 是否禁用
	 * 禁用返回true，否则返回false
	 */
	public function is_banned()
	{
		return $this->ci->session->userdata('s_banned') ? TRUE : FALSE;
	}
	
	/*
	 * 根据id,username,email返回用户
	 */
	protected function get_user($id)
	{
		$this->ci->load->model('user_model');
		if (is_numeric($id))
		{
			$condition['id'] = $id;
		}
		elseif (is_email($id))
		{
			$condition['email'] = $id;
		}
		else
		{
			$condition['username'] = $id;
		}
		$user_data = $this->ci->user_model->get_one($condition);
		return $user_data ? $user_data : FALSE;
	}
	
	/*
	 * 注册
	 * username	用户名
	 * password	密码
	 * email	邮箱
	 */
	public function register($username, $password, $email)
	{
		if ( ! $this->is_username_available($username))
		{
			$this->error = '用户名已经被注册';
			return FALSE;
		}
		
		if ( ! $this->is_email_available($email))
		{
			$this->error = '邮箱已经被注册';
			return FALSE;
		}
		$password = $this->password_hash($password);
		$active_key = $this->get_key();
		$data = array(
			'username' => $username,
			'password' => $password,
			'email' => $email,
			'active_key' => $active_key
		);
		$this->ci->load->model('user_model');
		if (FALSE===($id = $this->ci->user_model->insert($data)))
		{
			$this->error = '注册失败';
			return FALSE;
		}
		
		$this->send_active_email($id);

		return TRUE;
	}
	
	/*
	 * 发送激活邮件
	 */
	public function send_active_email($id)
	{
		$user_data = $this->get_user($id);
		if (FALSE===$user_data)
		{
			$this->error = '账号不存在';
			return FALSE;
		}
		
		if ($user_data['banned'])
		{
			$this->error = '账号已被禁用';
			return FALSE;
		}
		
		if ($user_data['active'])
		{
			$this->error = '账号无需激活';
			return FALSE;
		}
		
		$active_key = $this->get_key();
		if (FALSE===$this->ci->user_model->update(array('active_key'=>$active_key), $user_data['id']))
		{
			$this->error = '生成密钥失败';
			return FALSE;
		}
		
		$this->ci->config->load('auth', TRUE);
		$config = $this->ci->config->item('auth');
		$this->ci->load->helper('email');
		$href = site_url('auth/active/'.$id.'/'.$active_key);
		$subject = $user_data['username'].'欢迎注册'.$config['web_name'].'，请点击邮件中的链接激活账号';
		$message = $user_data['username'].'欢迎注册'.$config['web_name'].'，请点击右边链接激活账号：<a href="'.$href.'" target="_blank">'.$href.'</a>';
		if ( ! send_email($user_data['email'], $subject, $message))
		{
			$this->error = '发送激活邮件失败';
			return FALSE;
		}

		return TRUE;
	}

	/*
	 * 发送修改密码邮件
	 */
	public function send_rpassword_email($id)
	{
		$user_data = $this->get_user($id);
		if (FALSE===$user_data)
		{
			$this->error = '账号不存在';
			return FALSE;
		}
		
		if ($user_data['banned'])
		{
			$this->error = '账号已被禁用';
			return FALSE;
		}
		
		$rpassword_key = $this->get_key();
		if (FALSE===$this->ci->user_model->update(array('rpassword_key'=>$rpassword_key), $user_data['id']))
		{
			$this->error = '生成密钥失败';
			return FALSE;
		}
		
		$this->ci->load->helper('email');
		$subject = '请点击邮件中的链接修改密码';
		$href = site_url('auth/rpassword/'.$id.'/'.$rpassword_key);
		$message = '请点击右边链接修改密码：<a href="'.$href.'" target="_blank">'.$href.'</a>';
		if ( ! send_email($user_data['email'], $subject, $message))
		{
			$this->error = '发送修改密码邮件失败';
			return FALSE;
		}

		return TRUE;
	}

	/*
	 * 账号激活
	 * id	用户id或用户名或email
	 * key	激活key
	 */
	public function active($id, $key)
	{
		$this->ci->load->model('user_model');
		if (is_numeric($id))
		{
			$condition['id'] = $id;
		}
		elseif (is_email($id))
		{
			$condition['email'] = $id;
		}
		else
		{
			$condition['username'] = $id;
		}
		$user_data = $this->ci->user_model->get_one($condition, 'id,banned,active,active_key');
		
		if ( ! $user_data)
		{
			$this->error = '账号不存在';
			return FALSE;
		}
		
		if ($user_data['active'])
		{
			return TRUE;
		}
		
		if ($key!=$user_data['active_key'])
		{
			$this->error = '非法访问';
			return FALSE;
		}

		if ($user_data['banned'])
		{
			$this->error = '账号已被禁用';
			return FALSE;
		}
		
		$time = substr($user_data['active_key'], 32);

		if (($time+3600*24)<time())
		{
			$this->error = '激活邮件已经过期';
			return FALSE;
		}
		
		if (FALSE===$this->ci->user_model->update(array('active'=>1), $user_data['id']))
		{
			log_message('error', '用户账号激活失败，用户名：'.$user_data['username'].' 邮箱：'.$user_data['email']);
			$this->error = '激活失败';
			return FALSE;
		}
		
		return TRUE;
	}
	
	/*
	 * 登录
	 * id	用户名或email
	 * password	密码
	 * remember	是否记住登录
	 * 成功登录返回true，失败返回false
	 */
	public function login($id, $password, $remember = FALSE)
	{
		$this->ci->load->model('user_model');
		if (is_email($id))
		{
			$condition = array('email'=>$id);
		}
		else
		{
			$condition = array('username'=>$id);
		}
		$user_data = $this->ci->user_model->get_one($condition);
		if ( ! $user_data)
		{
			$this->error = '用户或密码错误';
			return FALSE;
		}
		
		$password = $this->password_hash($password);
		if ($password!==$user_data['password'])
		{
			$this->error = '用户或密码错误';
			return FALSE;
		}
		
		$this->set_session($user_data);
		return TRUE;
	}
	
	/*
	 * 登出
	 */
	public function logout()
	{
		if ($this->is_login())
		{
			$this->ci->session->sess_destroy();
		}
	}
	
	/*
	 * 修改密码
	 * id 账号，用户名或邮箱
	 * new_password	新密码
	 * old_password	旧密码
	 */
	public function change_password($old_password, $new_password)
	{
		$this->ci->load->model('user_model');
		
		$id = $this->get_user_id();
		
		$old_password = $this->password_hash($old_password);
		$new_password = $this->password_hash($new_password);
		
		$user_data = $this->ci->user_model->get($id);
		
		if ( ! $user_data)
		{
			$this->logout();
			$this->error = '用户不存在';
			return FALSE;
		}
		
		if ($user_data['banned'])
		{
			$this->logout();
			$this->error = '用户被禁用';
			return FALSE;
		}
		
		if ($old_password!=$user_data['password'])
		{
			$this->error = '旧密码错误';
			return FALSE;
		}
		
		if (FALSE===$this->ci->user_model->update(array('password'=>$new_password), $id))
		{
			$this->error = '修改密码失败';
			return FALSE;
		}
		return TRUE;
	}

	/*
	 * 修改邮箱
	 * id 账号，用户名或邮箱
	 * email	新邮箱
	 * password	密码
	 */
	public function change_email($password, $email)
	{
		$this->ci->load->model('user_model');
		
		$id = $this->get_user_id();
		
		$password = $this->password_hash($password);
		
		$user_data = $this->ci->user_model->get($id);
		
			if ( ! $user_data)
		{
			$this->logout();
			$this->error = '用户不存在';
			return FALSE;
		}
		
		if ($user_data['banned'])
		{
			$this->logout();
			$this->error = '用户被禁用';
			return FALSE;
		}
		
		if ($password!=$user_data['password'])
		{
			$this->error = '密码错误';
			return FALSE;
		}
		
		if ($user_data['email']!=$email && ! $this->is_email_available($email))
		{
			$this->error = '邮箱已经被注册';
			return FALSE;
		}
		
		if (FALSE===$this->ci->user_model->update(array('email'=>$email), $id))
		{
			$this->error = '修改邮箱失败';
			return FALSE;
		}
		return TRUE;
	}

	/*
	 * 忘记密码，发送邮件到用户邮箱，配合reset_password使用
	 */
	public function forgot_password($id)
	{
		
	}
	
	/*
	 * 判断忘记密码发送的邮件中给的key修改密码
	 */
	public function reset_password($new_password, $key)
	{
		
	}
	
	/*
	 * 登录后设置session
	 */
	protected function set_session($user_data)
	{
		$this->ci->load->model(array('role_model', 'permission_model'));
		$role_data = $this->ci->role_model->get_one(array('id'=>$user_data['role_id']));
		$permission_data = $this->ci->permission_model->get_one(array('role_id'=>$user_data['role_id']));
		
		$session = array(
			's_user_id' => intval($user_data['id']),
			's_username' => $user_data['username'],
			's_role_id' => intval($user_data['role_id']),
			's_role_name' => $role_data['name'],
			's_parent_role_id' => intval($role_data['parent_id']),
			's_permission' => $permission_data['data'],
			's_banned' => ($user_data['banned'] ? TRUE : FALSE),
			's_login' => TRUE
		);
		
		$this->ci->session->set_userdata($session);
	}
	
	/*
	 * 密码hash
	 */
	public function password_hash($password)
	{
		$this->ci->config->load('auth', TRUE);
		$md5_key = $this->ci->config->item('md5_key', 'auth');
		return md5($md5_key.$password.$md5_key);
	}
	
	/*
	 * 返回一个42字符的key
	 */
	protected function get_key()
	{
		$this->ci->load->helper('string');
		return md5(rand_string(10, 0)).time();
	}
	
	/*
	 * 用户名是否可用
	 * 可用返回true，不可返回false
	 */
	public function is_username_available($username)
	{
		$this->ci->load->model('user_model');
		return $this->ci->user_model->exist(array('username'=>$username)) ? FALSE : TRUE;
	}
	
	/*
	 * 邮箱是否可用
	 */
	public function is_email_available($email)
	{
		$this->ci->load->model('user_model');
		return $this->ci->user_model->exist(array('email'=>$email)) ? FALSE : TRUE;
	}

}